package com.sunday.common.mq.rabbit.study.base.e6_Header;

import com.rabbitmq.client.*;
import com.sunday.common.mq.rabbit.study.base.ConnectionUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * HEADERS("headers")
 * <p>
 * Headers类型的exchange使用的比较少，它也是忽略routingKey的一种路由方式。
 * 是使用Headers来匹配的。Headers是一个键值对，可以定义成Hashtable。
 * 发送者在发送的时候定义一些键值对，接收者也可以再绑定时候传入一些键值对，两者匹配的话，则对应的队列就可以收到消息。
 * 匹配有两种方式all和any。这两种方式是在接收端必须要用键值"x-mactch"来定义。
 * all代表定义的多个键值对都要满足，而any则代码只要满足一个就可以了。
 * fanout，direct，topic exchange的routingKey都需要要字符串形式的，而headers exchange则没有这个要求，因为键值对的值可以是任何类型。
 * <p>
 * input a x-match any b c d e
 */
@Slf4j
public class ReceiveLogHeader {
    private static final String EXCHANGE_NAME = "header_test";

    public static void main(String[] argv) throws Exception {

        Scanner scan = new Scanner(System.in);//实例化Scanner对象
        log.info("请输入文本:");
        argv = scan.nextLine().split(" ");//接受用户输入的字符串

        if (argv.length < 1) {
            System.err.println("Usage: ReceiveLogsHeader queueName [headers]...");
            System.exit(1);
        }

        ConnectionFactory factory = ConnectionUtil.factory();

        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.HEADERS);

        String routingKeyFromUser = "ourTestRoutingKey";

        String queueInputName = argv[0];

        // The map for the headers.
        Map<String, Object> headers = new HashMap<>();

        for (int i = 1; i < argv.length; i++) {
            headers.put(argv[i], argv[i + 1]);
            log.info("Binding header {} and value {} to queue {}", argv[i], argv[i + 1], queueInputName);
            i++;
        }

        String queueName = channel.queueDeclare(queueInputName, false, false, false, null).getQueue();
        channel.queueBind(queueName, EXCHANGE_NAME, routingKeyFromUser, headers);

        log.info(" [*] Waiting for messages. To exit press CTRL+C");

        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            log.info("[x] Received '{}':'{}'", delivery.getEnvelope().getRoutingKey(), message);
        };
        channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {
        });
    }
}

